home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / sml_nj / 93src.lha / src / mips / mipsas.sml < prev    next >
Encoding:
Text File  |  1993-01-27  |  5.9 KB  |  192 lines

  1. structure MipsAsmStream = 
  2.     struct
  3.     val asmStream = ref std_out
  4.     end
  5.  
  6. functor MipsAsCode() : EMITTER = 
  7. struct
  8.  
  9. val error = ErrorMsg.impossible
  10.  
  11. structure M = MipsInstrSet
  12. open M
  13.  
  14. val loc = ref 0
  15. fun advance n = loc := !loc + n
  16.  
  17. local
  18.     val hexDigits = "0123456789abcdef"
  19.     fun f (0, l) = l
  20.       | f (n, l) =
  21.     (f(Bits.rshift(n,4),chr(ordof(hexDigits,Bits.andb(n,15)))::l))
  22.     fun cvt 0 = ["0","x","0"]
  23.       | cvt n = ("0"::"x"::f(n, nil))
  24. in
  25.     fun itoa i = implode(if (i < 0) then "-" :: cvt(~i) else cvt i)
  26. end
  27.  
  28. fun emit s = output(!MipsAsmStream.asmStream,s)
  29.  
  30. fun newLine() = emit "\n"
  31. fun emitLong i = (emit ".long\t"; emit(itoa i); newLine(); advance 4)
  32. local
  33.     fun oct i = let val m = Integer.makestring
  34.         in m(i quot 64)^m((i quot 8)mod 8)^m(i mod 8)
  35.         end
  36.     fun c_char "\n" = "\\n"
  37.       | c_char "\t" = "\\t"
  38.       | c_char "\\" = "\\\\"
  39.       | c_char "\"" = "\\\""
  40.       | c_char c = if ord c < 32 then "\\"^oct(ord c) else c
  41.     fun a_str s = implode(map c_char (explode s))
  42. in
  43.     fun emitString s = 
  44.     (emit ".ascii \""; emit(a_str s); emit "\"\n"; 
  45.      emit ".align\t4\n"; advance(size s))
  46. end 
  47.  
  48. fun emitReal r = (emit ".double\t"; emit r; newLine(); advance 8)
  49.  
  50. fun emitLabel (INFO{nameOf,...}) lab = emit(nameOf lab)
  51.  
  52. fun emitAddr (info as INFO{addrOf,...}) (lab, k) =
  53.     (emit "\t.long\t"; emitLabel info lab; 
  54.      emit "\t## "; emit(itoa(addrOf lab - !loc)); 
  55.      newLine(); advance 4)
  56.  
  57. fun define (info as INFO{addrOf,...}) lab =
  58.     (emitLabel info lab; emit ":\t## "; emit(itoa (addrOf lab)); newLine())
  59.  
  60. local open System.Tags
  61. in 
  62.     fun mark() = (emit "\t.long\tMAKE_DESC(((.-L0)/4+1),tag_backptr)\t## ";
  63.           emit (itoa (make_desc((!loc+4)quot 4,tag_backptr))); 
  64.           newLine(); advance 4)
  65. end 
  66.  
  67. fun emitInstr info =
  68.  let val labelValue = M.labelValue info
  69.      val hiLabelValue = M.hiLabelValue info
  70.      val loLabelValue = M.loLabelValue info
  71.      val labBranchOff = M.labBranchOff info
  72.  in fn I =>
  73.   let fun emitReg reg =
  74.           emit ("$" ^ (case reg_rep reg 
  75.                    of Reg' r =>  Integer.makestring r
  76.                   | Freg' fp => "f" ^ Integer.makestring fp))
  77.  
  78.       fun comma() = emit ", "
  79.  
  80.       fun emit_arithOpnd (RegOp r) = emitReg r
  81.     | emit_arithOpnd (Immed16Op i) = emit(makestring (chk_immed16 i))
  82.     | emit_arithOpnd lab =  
  83.         emit(makestring 
  84.            (case lab
  85.               of LabelOp labexp => labelValue labexp
  86.                | HiLabOp labexp => hiLabelValue labexp
  87.                | LoLabOp labexp => loLabelValue labexp))
  88.  
  89.       fun emit_memOpnd (Immed16Off i) = emit(makestring (chk_immed16 i))
  90.     | emit_memOpnd lab =
  91.         emit(makestring
  92.            (case lab
  93.               of LabOff labexp   => labelValue labexp
  94.                | HiLabOff labexp => hiLabelValue labexp
  95.                | LoLabOff labexp => loLabelValue labexp))
  96.  
  97.       fun emit_branchOpnd opnd =
  98.         emit(makestring(chk_immed16(labBranchOff opnd - (!loc + 4) div 4)))
  99.  
  100.       fun emit_arith(rd,rs,opnd) = 
  101.       (emitReg rd; comma(); emitReg rs; comma(); emit_arithOpnd opnd)
  102.     
  103.       fun emit_3regs(rd,rs,rt) = 
  104.       (emitReg rd; comma(); emitReg rs; comma(); emitReg rt)
  105.  
  106.       fun emit_2regs(rs,rt) = (emitReg rs; comma(); emitReg rt)
  107.  
  108.       fun emit_3float(fd,fs,ft) =
  109.       (emitReg fd; comma(); emitReg fs; comma(); emitReg ft)
  110.  
  111.       fun emit_2float(fs,ft) = (emitReg fs; comma(); emitReg ft)
  112.  
  113.       fun emit_mem(rd,base,offset) = 
  114.       (emitReg rd; comma(); emit_memOpnd offset; emit "(";
  115.        emitReg base; emit ")")
  116.  
  117.       fun emit_shift(rd,rt,Int5 i) = 
  118.       (emitReg rd; comma(); emitReg rt; comma(); emit(makestring i))
  119.  
  120.   in (emit "\t";
  121.       (case I 
  122.        of M.NOP         => emit "nop"
  123.  
  124.     | M.SLT arg         => (emit "slt\t"; emit_arith arg)
  125.     | M.SLTU arg        => (emit "sltu\t"; emit_arith arg)
  126.     | M.SLT_DOUBLE arg    => (emit "c.lt.d\t"; emit_2float arg)
  127.     | M.SEQ_DOUBLE arg    => (emit "c.eq.d\t"; emit_2float arg)
  128.  
  129.     | M.JUMP r          => (emit "jr\t"; emitReg r)
  130.     | M.BLTZAL()         => (emit "bltzal\t")
  131.     | M.BEQ(cond,r1,r2,offset)
  132.                   => (emit(if cond then "beq\t" else "bne\t");
  133.                     emitReg r1; comma();
  134.                     emitReg r2; comma(); 
  135.                     emit_branchOpnd offset)
  136.     | M.BCOP1(cond,offset)  => (emit(if cond then "bc1t\t" else "bc1f\t");
  137.                     emit_branchOpnd offset)
  138.  
  139.     | M.ADD arg        => (emit "add\t"; emit_arith arg)
  140.     | M.ADDU arg         => (emit "addu\t";emit_arith arg)
  141.     | M.AND arg        => (emit "and\t"; emit_arith arg)
  142.     | M.OR arg        => (emit "or\t";  emit_arith arg)
  143.     | M.XOR arg        => (emit "xor\t"; emit_arith arg)
  144.     | M.SUB arg        => (emit "sub\t"; emit_3regs arg)
  145.  
  146.     | M.MULT arg             => (emit "mult\t"; emit_2regs arg)
  147.     | M.DIV arg        => (emit "div\t"; emit_2regs arg)
  148.     | M.MFLO r         => (emit "mflo\t"; emitReg r)
  149.     | M.MFHI r         => (emit "mfhi\t"; emitReg r)
  150.     | M.BREAK i         => (emit "break\t"; emit(makestring i))
  151.  
  152.     | M.MUL_DOUBLE arg    => (emit "mul.d\t"; emit_3float arg)
  153.     | M.DIV_DOUBLE arg    => (emit "div.d\t"; emit_3float arg)
  154.     | M.ADD_DOUBLE arg    => (emit "add.d\t"; emit_3float arg)
  155.     | M.SUB_DOUBLE arg    => (emit "sub.d\t"; emit_3float arg)
  156.     | M.NEG_DOUBLE arg    => (emit "neg.d\t";   emit_2float arg)
  157.     | M.ABS_DOUBLE arg    => (emit "abs.d\t";   emit_2float arg)
  158.     | M.CVTI2D arg          => (emit "cvt.d.s\t"; emit_2float arg)
  159.     | M.MTC1 arg            => (emit "mtc1\t"; emit_2regs arg)
  160.  
  161.     | M.MOV_DOUBLE arg    => (emit "mov.d\t"; emit_2float arg)
  162.  
  163.     | M.LBU arg         => (emit "lbu\t";  emit_mem arg)
  164.     | M.SB arg         => (emit "sb\t";   emit_mem arg)
  165.     | M.LW arg         => (emit "lw\t";   emit_mem arg)
  166.     | M.SW arg         => (emit "sw\t";   emit_mem arg)
  167.     | M.LWC1 arg             => (emit "lwc1\t"; emit_mem arg)
  168.     | M.SWC1 arg             => (emit "swc1\t"; emit_mem arg)
  169.     | M.LUI(r,mOff)         => (emit "lui\t"; emitReg r; comma();
  170.                     emit_memOpnd mOff)
  171.     | M.SLL arg        => (emit "sll\t"; emit_shift arg)
  172.     | M.SRA arg        => (emit "sra\t"; emit_shift arg)
  173.     | M.SLLV arg         => (emit "sllv\t"; emit_3regs arg)
  174.         | M.SRAV arg         => (emit "srav\t"; emit_3regs arg));
  175.      newLine();
  176.      advance 4)
  177.   end
  178.  end
  179.  
  180. fun comment s = emit ("#" ^ s ^ "\n")
  181.  
  182. fun init(n:int) = 
  183.     (loc := 0; emit "## code size = "; emit (makestring n ^ " bytes\n"));
  184. end
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.